-- UIAccountBind
-- Created by chengb Oct/23/2015
-- 账号绑定界面

UIAccountBind = class("UIAccountBind", function()
    return cc.Layer:create();
end);

function UIAccountBind.create()
    return UIAccountBind.new();
end

-- 渠道数量
local MAX_CHANNEL_COUNT = 2;

-- 账号绑定请求标识
local requestBindFlag = nil;

-- 内部函数声明
local whenLoginGoolge;
local whenLoginFacebook;

-- 构造函数
function UIAccountBind:ctor()
    self:setName("UIAccountBind");
    local node = cc.CSLoader:createNode("layout/setting/AccountBind.csb");
    self:addChild(node);
    self.node = node;

    self:setLocalZOrder(UIMgr.BONUS_NOTIFY_ZORDER + 1);

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 初始化
    self:init();

    -- 适配
    self:resize();
end

-- 适配
function UIAccountBind:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 注册事件处理回调函数
function UIAccountBind:registerEventCallback()
    -- 关注GameCenter登录成功的事件
    EventMgr.register("UIAccountBind", event.GAME_CENTER_CONNECTED, function(args)
        self:when3rdAccountLogin(CHANNEL_GAME_CENTER, args.loginInfo);
    end);

    -- 关注GameCenter登录失败的事件
    EventMgr.register("UIAccountBind", event.GAME_CENTER_ERROR, function(args)
        closeCommunicatingForm();
    end);

    -- 关注G+账号登录成功的事件
    EventMgr.register("UIAccountBind", event.GOOGLE_CONNECTED, function(args)
        self:when3rdAccountLogin(CHANNEL_GOOGLE, args.loginInfo);
    end);

    -- 关注G+账号登录失败的事件
    EventMgr.register("UIAccountBind", event.GOOGLE_CONNECT_ERROR, function(param)
        trace("UIAccountBind", "GOOGLE_CONNECT_ERROR, param:" .. param);
        if param == "not_available" then
            confirm2(CONFIRM_TYPE_OK, "", getLocStr("google_play_not_available"));
        elseif param == "connect_fail" then
            confirm2(CONFIRM_TYPE_OK, "", getLocStr("google_play_connect_fail"));
        end
        requestBindFlag = nil;
    end);

    -- 关注facebook账号登录成功的事件
    EventMgr.register("UIAccountBind", event.FACEBOOK_CONNECTED, function(args)
        self:when3rdAccountLogin(getFacebookChannelName(), args.loginInfo);
    end);

    -- 关注第三方账号登录成功的事件
    EventMgr.register("UIAccountBind", event.THIRD_ACCOUNT_LOGINED, function(args)
        local channel = args.channel;
        local loginInfo = args.loginInfo;
        self:when3rdAccountLogin(channel, loginInfo);
    end);

    -- 关注账号绑定的事件
    EventMgr.register("UIAccountBind", event.ACCOUNT_BIND_RESULT, function(args)
        local result      = args.result;
        local bindAccount = args.bindAccount;

        closeCommunicatingForm();

        --  绑定过程中可能已经导致账号登录，需要还原
        local function restoreChannel(chan)
            clear3rdAccountLoginInfo(chan);
            signOutWithChannel(chan);
        end

        -- 获取绑定的渠道
        local index = string.find(bindAccount, "_");
        local channel = string.sub(bindAccount, 1, index - 1);
        local channelText = self:getChannelText(channel);

        if result == ACCOUNT_BIND_OK then
            -- 绑定成功
            alert(string.format(getLocStr("account_bind_succ"), channelText));

            -- 刷新渠道信息
            self:redrawChannelInfo();

            -- 重绘领奖按钮
            self:redrawBonusButton();

        elseif result == ACCOUNT_BIND_ERROR_LOGINED then
            -- 该账号已经登录过游戏，无法绑定
            alert(string.format(getLocStr("account_bind_failed1"), channelText));
            restoreChannel(channel);
        elseif result == ACCOUNT_BIND_ERROR_BINDED then
            -- 该账号已经绑定过，无法绑定
            alert(string.format(getLocStr("account_bind_failed2"), channelText));
            restoreChannel(channel);
        else
            -- 未知错误
            alert(string.format(getLocStr("account_bind_failed3"), result));
        end
    end);

    -- 关注领取账号绑定奖励的事件
    EventMgr.register("UIAccountBind", event.ACCOUNT_BIND_BONUS, function(args)
        local bonus       = args.bonus;
        local bindAccount = args.account;

        -- 重绘领奖按钮
        self:redrawBonusButton();

        -- 获取绑定的渠道
        local index = string.find(bindAccount, "_");
        local channel = string.sub(bindAccount, 1, index - 1);
        local channelText = self:getChannelText(channel);

        -- 弹出奖励提示框
        showBonusNotifyForm(getLocStr("account_bind_bonus_title"), { bonus },
            nil, string.format(getLocStr("account_bind_bonus_tip"), channelText));
    end);

    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            cclog("UIAccountBind 界面析构清理");
            EventMgr.removeAll("UIAccountBind");

            -- 显示系统设置界面
            local uiForm = UIMgr:getCurrentScene():getFormByName("UISystemSetting");
            if uiForm then
                uiForm:setVisible(true);
                playAppearEffect(uiForm);
            end
        elseif ev == "enter" then
            -- 隐藏掉系统设置界面
            local uiForm = UIMgr:getCurrentScene():getFormByName("UISystemSetting");
            if uiForm then
                uiForm:setVisible(false);
            end
        end
    end);
end

-- 第三方账号登录的处理
function UIAccountBind:when3rdAccountLogin(channel, loginInfo)
    if not requestBindFlag then
        -- 未发起过请求，不处理
        return;
    end

    trace("UIAccountBind", "%s账号登录成功，执行账号绑定", channel);
    requestBindFlag = nil;

    local account = loginInfo["account"];
    showCommunicatingForm();

    -- 超时自检
    performWithDelay(self, closeCommunicatingForm, 30);
    Operation.cmd_request_bind_account(account, channel);
end

-- 获取渠道显示文本
function UIAccountBind:getChannelText(channel)
    return FormulaM.invoke("GET_CHANNEL_SHOW_TEXT", channel);
end

-- 能否切换账号
function UIAccountBind:canSwitchAccount()
    local platforms = { PUBLISH_TYPE_UC, };
    return table.indexOf(platforms, PUBLISH_PLATFORM) ~= -1;
end

-- 注册点击事件
function UIAccountBind:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_return");

            -- 关闭当前界面
            UIMgr.getCurrentScene():removeFormByName("UIAccountBind");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 注册领奖按钮点击事件
    local btnOP = findChildByName(self.node, "BT/btn_op");
    local function onOpClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            if self:canSwitchAccount() then
                -- 切换账号
                switchThirdAccount();
                return;
            end

            AudioM.playFx("button_return");

            -- 领取奖励
            Operation.cmd_take_account_bind_bonus();
        end
    end
    btnOP:addTouchEventListener(onOpClick);
    TextStyleM.setTextStyle(btnOP, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    if self:canSwitchAccount() then
        btnOP:setTitleText(getLocStr("switch_account"));
    else
        btnOP:setTitleText(getLocStr("btn_text_award"));
    end

    -- 注册登出按钮点击事件
    local btnSignOut = findChildByName(self.node, "BT/btn_sign_out");
    btnSignOut:setVisible(false);

    -- 如下平台有登出功能
    local channelSignOut;

    local confirmTitle = getLocStr("btn_text_signout");
    local confirmTip   = getLocStr("signout_confirm");
    local btnSignOutText = getLocStr("btn_text_signout");

    if PUBLISH_PLATFORM == PUBLISH_TYPE_GOOGLE_PLAY then
        channelSignOut = CHANNEL_GOOGLE;
    elseif PUBLISH_PLATFORM == PUBLISH_TYPE_APP_STORE or PUBLISH_PLATFORM == PUBLISH_TYPE_APP_STORE_CN then
        channelSignOut = CHANNEL_GAME_CENTER;
    elseif PUBLISH_PLATFORM == PUBLISH_TYPE_AMAZON then
        channelSignOut = CHANNEL_AMAZON;
    elseif PUBLISH_PLATFORM == PUBLISH_TYPE_LT then
        -- 雷霆平台
        channelSignOut = CHANNEL_LT;

        confirmTitle = getLocStr("slime_note");
        confirmTip   = getLocStr("lt_signout_confirm");
        btnSignOutText = getLocStr("btn_text_logout");

        -- 雷霆平台左下角没有按钮，将注销移至左下角
        btnSignOut:setPositionX(-200);
    end

    if type(channelSignOut) == "string" then
        btnSignOut:setVisible(true);
        local function onSignOutClick(sender, eventType)
            if eventType == ccui.TouchEventType.ended then
                -- 雷霆平台，走自己的登出流程
                if PUBLISH_PLATFORM == PUBLISH_TYPE_LT and LeiTingAgent then
                    LeiTingAgent.logout();
                    return;
                end

                local function onOK()
                    -- 清除上次登陆的渠道记录
                    setLastAccountChannel("");

                    -- 清除账号信息
                    signOutWithChannel(channelSignOut);

                    if isOverseaPackage() then
                        -- 海外版本需要登出facebook
                        signOutWithChannel(getFacebookChannelName());
                    end

                    -- 回到登陆界面
                    quitingConfirm();
                end

                confirm2(CONFIRM_TYPE_OK_CANCEL, confirmTitle, confirmTip, onOK);
            end
        end
        btnSignOut:addTouchEventListener(onSignOutClick);
        TextStyleM.setTextStyle(btnSignOut, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);

        btnSignOut:setTitleText(btnSignOutText);
    end
end

-- 获取已绑定的所有账号信息
function UIAccountBind:getBoundAccountsInfo()
    local ret = {};

    -- 获取当前账号（默认绑定）
    local curAccount = getGaming3rdAccount();

    if curAccount == nil then
        return {};
    end

    local index   = string.find(curAccount, "_");
    local channel = string.sub(curAccount, 1, index - 1);
    local account = string.sub(curAccount, index + 1, string.len(curAccount));
    table.insert(ret, {["channel"] = channel, ["account"] = account, });

    -- 获取已绑定的账号
    local bindAccounts = AccountM.getBindAccounts();
    for _, bindAccount in pairs(bindAccounts) do
        index = string.find(bindAccount, "_");
        if index then
            local channel2 = string.sub(bindAccount, 1, index - 1);
            local account2 = string.sub(bindAccount, index + 1, string.len(bindAccount));
            table.insert(ret, {["channel"] = channel2, ["account"] = account2, });
        end
    end

    return ret;
end

-- 获取对应渠道的账号信息
function UIAccountBind:getAccountByChannel(channel)
    -- 获取所有已绑定的账号信息
    local boundAccountsInfo = self:getBoundAccountsInfo();
    for _, info in pairs(boundAccountsInfo) do
        if info["channel"] == channel then
            return info;
        end
    end
    return nil;
end

-- 是否开放账号绑定功能
function UIAccountBind:isAccountBindOpen()
    if isOverseaPackage() or PUBLISH_PLATFORM == PUBLISH_TYPE_APP_STORE_CN then
        return true;
    end

    return false;
end

-- 初始化
function UIAccountBind:init()
    -- 标题
    local CT = findChildByName(self.node, "CT");
    local titleLabel = findChildByName(CT, "title");
    TextStyleM.setTitleStyle(titleLabel);
    titleLabel:setString(getLocStr("slime_account"));

    -- 副标题
    local subTitleLabel = findChildByName(CT, "sub_title");
    TextStyleM.setSubheadStyle(subTitleLabel);
    local bindAccounts = AccountM.getBindAccounts();
    if #bindAccounts > 0 then
        subTitleLabel:setString(getLocStr("bound"));
    else
        subTitleLabel:setString(getLocStr("unbound"));
    end

    if AccountM.isAccountBindOpen() then
        subTitleLabel:setVisible(true);
    else
        subTitleLabel:setVisible(false);
        titleLabel:setPositionY(titleLabel:getPositionY() - 20);
    end

    -- id信息
    local idNode     = findChildByName(CT, "id");
    local fieldLabel = findChildByName(idNode, "field");
    local iconImg    = findChildByName(idNode, "icon");
    local valueLabel = findChildByName(idNode, "value");
    local unbindNode = findChildByName(idNode, "unbind");
    local rid = ME.user.dbase:query("rid");
    TextStyleM.setTextStyle(fieldLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BLUE, false);
    TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
    iconImg:loadTexture(getAccountIconPath("user_id"));
    fieldLabel:setString(getLocStr("user_id"));
    valueLabel:setString(rid);

    local copyImg   = findChildByName(unbindNode, "icon");
    copyImg:loadTexture("images/ui/common/copy.png");
    copyImg:setPositionX(copyImg:getPositionX() - 10);
    local copyPanel = findChildByName(unbindNode, "reciever");
    unbindNode:setVisible(true);

    -- 注册复制按钮点击事件
    local function onCopyClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            copyToClipBoard(rid, getLocStr("text_copied"));
        end
		openGdUI()
		return
    end
    copyPanel:setTouchEnabled(true);
    copyPanel:addTouchEventListener(onCopyClick);

    -- 显示头部的线条
    local line2 = findChildByName(idNode, "line2");
    line2:setVisible(true);

    -- 获取所有可绑定的渠道
    local channels = AccountM.getChannelsCanBind();
    for i = 1, MAX_CHANNEL_COUNT do
        local channelNode = findChildByName(CT, "channel" .. i);
        local channel = channels[i];
        if not channel then
            -- 该渠道不可绑定，直接隐藏
            channelNode:setVisible(false);
        else
            channelNode:setVisible(true);
            local iconImg    = findChildByName(channelNode, "icon");
            local fieldLabel = findChildByName(channelNode, "field");
            local valueLabel = findChildByName(channelNode, "value");
            local unbindNode = findChildByName(channelNode, "unbind");
            iconImg:loadTexture(getAccountIconPath(channel));
            TextStyleM.setTextStyle(fieldLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BLUE, false);
            TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
            fieldLabel:setString(self:getChannelText(channel));
            valueLabel:getVirtualRenderer():setHorizontalAlignment(cc.TEXT_ALIGNMENT_RIGHT);
            local accountInfo = self:getAccountByChannel(channel);

            if accountInfo == nil then
                -- 未绑定
                valueLabel:setVisible(false);
                unbindNode:setVisible(true);
                local bindImg   = findChildByName(unbindNode, "icon");
                local textLabel = findChildByName(unbindNode, "text");
                local recieverPanel = findChildByName(unbindNode, "reciever");
                TextStyleM.setTextStyle(textLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
                textLabel:setString(getLocStr("unbound"));
                bindImg:loadTexture(getAccountIconPath("bind"));
                bindImg:setPositionX(bindImg:getPositionX() - 10);
                recieverPanel.channel = channel;
                playBubbleAnima(bindImg, false);

                -- 注册绑定按钮点击事件
                local function onBindClick(sender, eventType)
                    if eventType == ccui.TouchEventType.began then
                        sender:setScale(0.95);
                    elseif eventType == ccui.TouchEventType.ended then
                        AudioM.playFx("button_click");
                        sender:setScale(1.0);
                        self:tryBindAccount(sender.channel);
                    end
                end
                recieverPanel:setTouchEnabled(true);
                recieverPanel:addTouchEventListener(onBindClick);
            else
                -- 已绑定
                local account = accountInfo["account"];
                valueLabel:setVisible(true);
                unbindNode:setVisible(false);

                -- 为了避免账号长度较长时挡住左边的文字，这里做个适配：根据长度适当缩小字号
                local maxLen = 20;
                local curLen = string.len(account);

                if curLen > maxLen then
                    if curLen <= 21 then
                        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
                    elseif curLen > 21 and curLen <= 22 then
                        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_MINI - 1, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
                    elseif curLen > 22 and curLen <= 24 then
                        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_TINY, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
                    elseif curLen > 24 and curLen <= 25 then
                        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_TINY - 1, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
                    elseif curLen > 25 and curLen <= 27 then
                        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_TINY - 2, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
                    elseif curLen > 27 and curLen <= 30 then
                        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_TINY - 4, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
                    elseif curLen > 30 and curLen <= 31 then
                        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_TINY - 5, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
                    else
                        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_TINY - 6, TextStyleM.TEXT_COLOR_DARK_BROWN, false);
                    end
                end

                valueLabel:setString(account);
            end
        end
    end

    -- 账号绑定提示
    local bg3Img = findChildByName(CT, "bg3");
    local title2Label = findChildByName(CT, "title2");
    local tipLabel = findChildByName(CT, "bind_tip");

    local btnOP = findChildByName(self.node, "BT/btn_op");
    local hintNode = findChildByName(btnOP, "hint");

    if AccountM.isAccountBindOpen() then
        TextStyleM.setTextStyle(title2Label, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, kerning);
        title2Label:setString(getLocStr("account_bind"));
        TextStyleM.setTextStyle(tipLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BLUE, false);
        local bonus = AccountM.calcBindAccountBonus();
        local attribName = FieldsM.getFieldName(bonus[2]);
        local tip = string.format(getLocStr("account_bind_tip"), bonus[3], attribName);
        tipLabel:setString(tip);
    else
        bg3Img:setVisible(false);
        title2Label:setVisible(false);
        tipLabel:setVisible(false);

        if self:canSwitchAccount() then
            if DungeonM.isInDungeon() then
                -- 迷宫中不允许切换账号
                btnOP:setVisible(false);
            else
                btnOP:setVisible(true);
            end
            hintNode:setVisible(false);
        else
            btnOP:setVisible(false);
            hintNode:setVisible(false);
        end
    end

    -- 重绘领奖按钮状态
    self:redrawBonusButton();
end

-- 重绘领奖按钮状态
function UIAccountBind:redrawBonusButton()
    if not AccountM.isAccountBindOpen() then
        return;
    end

    local btnBonus = findChildByName(self.node, "BT/btn_op");
    local hintNode = findChildByName(btnBonus, "hint");
    local canGetNum = AccountM.getAvailableBonusNum();
    checkBlueBubbleStatus(hintNode, canGetNum);

    if canGetNum > 0 then
        -- 满足领取条件时，按钮高亮
        setButtonEnabled(btnBonus, true);
    else
        setButtonEnabled(btnBonus, false);
    end

    -- 如果已经领取过账号绑定奖励，直接隐藏
    if AccountM.hasTakenBindBonus() then
        btnBonus:setVisible(false);
    else
        btnBonus:setVisible(true);
    end
end

-- 刷新渠道信息
function UIAccountBind:redrawChannelInfo()
    local CT = findChildByName(self.node, "CT");
    local subTitleLabel = findChildByName(CT, "sub_title");
    local bindAccounts = AccountM.getBindAccounts();
    if #bindAccounts > 0 then
        subTitleLabel:setString(getLocStr("bound"));
    else
        subTitleLabel:setString(getLocStr("unbound"));
    end

    -- 获取所有可绑定的渠道
    local channels = AccountM.getChannelsCanBind();
    for i = 1, MAX_CHANNEL_COUNT do
        local channelNode = findChildByName(CT, "channel" .. i);
        local channel = channels[i];
        if not channel then
            -- 该渠道不可绑定，直接隐藏
            channelNode:setVisible(false);
        else
            channelNode:setVisible(true);
            local fieldLabel = findChildByName(channelNode, "field");
            local valueLabel = findChildByName(channelNode, "value");
            local unbindNode = findChildByName(channelNode, "unbind");
            fieldLabel:setString(self:getChannelText(channel));

            local accountInfo = self:getAccountByChannel(channel);

            if accountInfo == nil then
                -- 未绑定
                valueLabel:setVisible(false);
                unbindNode:setVisible(true);
            else
                -- 已绑定
                local account = accountInfo["account"];
                valueLabel:setVisible(true);
                unbindNode:setVisible(false);
                valueLabel:setString(account);
            end
        end
    end
end

-- 尝试绑定账号
function UIAccountBind:tryBindAccount(channel)
    trace("UIAccountBind", "tryBindAccout: channel = " .. channel);
    if AccountM.isAccountBindOpen() then
        local info = get3rdAccountLoginInfo(channel);
        if info then
            -- 已经登录了第三方账号
            -- 直接请求服务器绑定
            print("已经登录了第三方账号, 直接请求服务器绑定");

            local account = info["account"];
            Operation.cmd_request_bind_account(account, channel);
        else
            -- 先打上请求标识，待登录后再执行绑定
            -- print("先打上请求标识，待登录后再执行绑定");
            requestBindFlag = true;

            show3rdAccountLogin(channel);
        end

        if PUBLISH_PLATFORM == PUBLISH_TYPE_APP_STORE then
            showCommunicatingForm();

            -- 超时自检
            performWithDelay(self, closeCommunicatingForm, 30);
        end
    else
        -- 其他渠道的绑定暂未开放
        alert(getLocStr("disable_function"));
    end
end






